<template>
  <div class="hacker-terminal">
    <div class="terminal-header">
      <div class="terminal-controls">
        <span class="control-dot red"></span>
        <span class="control-dot yellow"></span>
        <span class="control-dot green"></span>
      </div>
    </div>
    <div class="terminal-body" ref="terminalBody">
      <div class="terminal-content">
        <div
          v-for="line in displayLines"
          :key="line.id"
          class="terminal-line"
          :class="{ typing: line.isTyping, completed: line.isCompleted }"
          :style="{
            transform: `translateY(${line.yOffset}px)`,
            opacity: line.opacity,
          }"
        >
          <span class="prompt"></span>
          <span class="command">{{ line.displayText }}</span>
          <span v-if="line.isTyping && line.displayText" class="cursor">█</span>
        </div>
      </div>
      <div class="scan-line"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'

const props = defineProps({
  items: {
    type: Array,
    default: () => [],
  },
  speed: {
    type: Number,
    default: 1000, // 打字速度（毫秒/字符）
  },
  height: {
    type: Number,
    default: 35, // 每行高度
  },
})

const terminalBody = ref(null)
const displayLines = ref([])
const currentLineIndex = ref(0)
const typingTimer = ref(null)
const scrollTimer = ref(null)
const lineIdCounter = ref(0)

// 测试数据
const testItems = [
  { description: '等待知识搜索结果...' }
]

// 计算显示的项目
const computedItems = computed(() => {
  return props.items.length > 0 ? props.items : [{ description: '等待知识搜索结果...' }]
})

// 创建新行
const createNewLine = (text) => {
  return {
    id: lineIdCounter.value++,
    fullText: text,
    displayText: '',
    currentCharIndex: 0,
    isTyping: true,
    isCompleted: false,
    yOffset: 0,
    opacity: 1,
  }
}

// 将长文本分割成多行
const splitTextIntoLines = (text, maxLength = 100) => {
  if (!text) return ['等待知识搜索结果...']
  
  const lines = []
  
  // 首先按句子分割（中文句号、英文句号等）
  const sentences = text.split(/[。！？；\n]/).filter(s => s.trim())
  
  let currentLine = ''
  
  sentences.forEach(sentence => {
    sentence = sentence.trim()
    if (!sentence) return
    
    // 如果单个句子就很长，需要强制分割
    if (sentence.length > maxLength) {
      // 先保存当前行
      if (currentLine.trim()) {
        lines.push(currentLine.trim())
        currentLine = ''
      }
      
      // 分割长句子
      for (let i = 0; i < sentence.length; i += maxLength) {
        lines.push(sentence.substring(i, i + maxLength))
      }
    } else {
      // 如果当前行加上新句子超过最大长度，就开始新行
      if (currentLine && (currentLine + sentence).length > maxLength) {
        lines.push(currentLine.trim())
        currentLine = sentence
      } else {
        currentLine += (currentLine ? ' ' : '') + sentence
      }
    }
  })
  
  // 添加最后一行
  if (currentLine.trim()) {
    lines.push(currentLine.trim())
  }
  
  // 如果没有分割出任何行，就按字符数强制分割
  if (lines.length === 0 && text.length > 0) {
    for (let i = 0; i < text.length; i += maxLength) {
      lines.push(text.substring(i, i + maxLength))
    }
  }
  
  return lines.length > 0 ? lines : [text || '等待知识搜索结果...']
}

// 开始显示效果
const startTyping = () => {
  console.log('KnowledgeCarousel: 开始显示效果')
  
  if (currentLineIndex.value >= computedItems.value.length) {
    currentLineIndex.value = 0
  }

  const currentItem = computedItems.value[currentLineIndex.value]
  
  if (!currentItem || !currentItem.description) {
    console.warn('KnowledgeCarousel: 当前项目无效', currentItem)
    return
  }
  
  // 将长文本分割成多行
  const textLines = splitTextIntoLines(currentItem.description)
  console.log('KnowledgeCarousel: 分割成', textLines.length, '行')
  
  // 逐行添加，创建滚动效果
  let lineIndex = 0
  
  const addNextLine = () => {
    // 如果页面不可见，暂停添加新行
    if (!isPageVisible.value) {
      console.log('KnowledgeCarousel: 页面不可见，暂停添加新行')
      setTimeout(addNextLine, 2000) // 2秒后重试
      return
    }
    
    if (lineIndex >= textLines.length) {
      // 当前项目的所有行都显示完了，等待后显示下一个项目
      const nextItemTimeout = setTimeout(() => {
        if (!isPageVisible.value) return // 再次检查页面可见性
        
        currentLineIndex.value++
        if (currentLineIndex.value < computedItems.value.length) {
          startTyping()
        } else if (computedItems.value.length > 1) {
          // 重新开始循环
          currentLineIndex.value = 0
          setTimeout(() => {
            if (isPageVisible.value) startTyping()
          }, 3000)
        }
      }, 2000)
      
      // 保存定时器引用
      typingTimer.value = nextItemTimeout
      return
    }
    
    const newLine = createNewLine(textLines[lineIndex])
    
    // 新行初始位置在底部
    newLine.yOffset = 0
    newLine.opacity = 1
    newLine.displayText = newLine.fullText
    newLine.isTyping = false
    newLine.isCompleted = true

    // 添加新行到显示列表
    displayLines.value.push(newLine)
    console.log('KnowledgeCarousel: 添加了新行，总数:', displayLines.value.length)

    // 立即重新计算所有行的位置，这会触发CSS动画
    nextTick(() => {
      startScrollUp()
    })
    
    lineIndex++
    
    // 1.5秒后添加下一行
    const nextLineTimeout = setTimeout(addNextLine, 1500)
    typingTimer.value = nextLineTimeout
  }
  
  // 开始添加第一行
  addNextLine()
}

// 渐进式文本显示
const animateTextDisplay = (line) => {
  if (!line || !line.fullText) return
  
  const totalLength = line.fullText.length
  const duration = 2000 // 2秒内显示完整文本
  
  let currentIndex = 0
  
  const displayInterval = setInterval(() => {
    if (currentIndex >= totalLength) {
      // 显示完成
      line.displayText = line.fullText
      line.isTyping = false
      line.isCompleted = true
      clearInterval(displayInterval)
      
      // 等待后开始下一行，但要检查是否还有更多项目
      setTimeout(() => {
        if (currentLineIndex.value + 1 < computedItems.value.length) {
          currentLineIndex.value++
          startTyping()
        } else {
          // 如果没有更多项目，重置到开头（如果有多个项目的话）
          if (computedItems.value.length > 1) {
            currentLineIndex.value = 0
            setTimeout(() => startTyping(), 3000) // 等待3秒后重新开始
          }
        }
      }, 2000)
      return
    }
    
    currentIndex += Math.max(1, Math.floor(totalLength / 15)) // 每次显示更多内容
    line.displayText = line.fullText.substring(0, currentIndex)
  }, 100) // 固定100ms间隔
  
  // 保存interval引用以便清理
  typingTimer.value = displayInterval
}

// 向上滑动效果
const startScrollUp = () => {
  const fixedLineHeight = 80 // 使用固定的大行高，确保不重叠
  
  displayLines.value.forEach((line, index) => {
    // 最新的行在底部，往上排列
    const reverseIndex = displayLines.value.length - 1 - index
    line.yOffset = -reverseIndex * fixedLineHeight
    
    // 根据位置设置透明度
    if (reverseIndex > 3) {
      line.opacity = Math.max(0.3, 1 - (reverseIndex - 3) * 0.2)
    } else {
      line.opacity = 1
    }
    
    console.log(`行 ${index}: yOffset=${line.yOffset}, opacity=${line.opacity}`)
  })

  // 只保留最新的5行
  if (displayLines.value.length > 5) {
    displayLines.value = displayLines.value.slice(-5)
  }
}

// 初始化 - 简化版本
const init = () => {
  console.log('KnowledgeCarousel: 简化初始化')
  cleanup()
  displayLines.value = []
  currentLineIndex.value = 0
  lineIdCounter.value = 0
  startTyping()
}

// 清理定时器
const cleanup = () => {
  console.log('KnowledgeCarousel: 清理定时器')
  if (typingTimer.value) {
    clearTimeout(typingTimer.value)
    clearInterval(typingTimer.value) // 同时清理interval
    typingTimer.value = null
    console.log('KnowledgeCarousel: 已清理显示定时器')
  }
  if (scrollTimer.value) {
    clearTimeout(scrollTimer.value)
    scrollTimer.value = null
    console.log('KnowledgeCarousel: 已清理滚动定时器')
  }
}

// 页面可见性状态
const isPageVisible = ref(true)
const resumeTimer = ref(null)

// 处理页面可见性变化
const handleVisibilityChange = () => {
  if (document.hidden) {
    isPageVisible.value = false
    console.log('KnowledgeCarousel: 页面隐藏，暂停滚动')
  } else {
    isPageVisible.value = true
    console.log('KnowledgeCarousel: 页面可见，恢复滚动')
    
    // 页面重新可见时，恢复滚动
    if (resumeTimer.value) {
      clearTimeout(resumeTimer.value)
    }
    
    resumeTimer.value = setTimeout(() => {
      // 如果当前没有正在进行的动画，重新启动
      if (displayLines.value.length === 0 || !typingTimer.value) {
        console.log('KnowledgeCarousel: 重新启动滚动')
        startTyping()
      }
    }, 1000)
  }
}

// 组件挂载
onMounted(() => {
  console.log('KnowledgeCarousel: 组件已挂载')
  
  // 监听页面可见性变化
  document.addEventListener('visibilitychange', handleVisibilityChange)
  
  // 直接启动
  setTimeout(() => {
    startTyping()
  }, 500)
})

// 组件卸载
onUnmounted(() => {
  cleanup()
  
  // 清理页面可见性监听器
  document.removeEventListener('visibilitychange', handleVisibilityChange)
  
  // 清理恢复定时器
  if (resumeTimer.value) {
    clearTimeout(resumeTimer.value)
  }
})

// 监听props变化
watch(
  () => props.items,
  (newItems) => {
    console.log('KnowledgeCarousel: items变化', newItems?.length)
    if (newItems && newItems.length > 0) {
      // 有新数据时，重新开始显示
      cleanup()
      displayLines.value = []
      currentLineIndex.value = 0
      setTimeout(() => {
        startTyping()
      }, 100)
    }
  },
  { deep: true }
)
</script>

<style scoped>
.hacker-terminal {
  width: 100%;
  height: 100%;
  background:
    linear-gradient(
      135deg,
      rgba(0, 5, 20, 0.95) 0%,
      rgba(10, 0, 30, 0.95) 50%,
      rgba(0, 10, 40, 0.95) 100%
    ),
    repeating-linear-gradient(
      0deg,
      transparent,
      transparent 2px,
      rgba(0, 150, 255, 0.03) 2px,
      rgba(0, 150, 255, 0.03) 4px
    );
  border: 2px solid #00aaff;
  border-radius: 8px;
  box-shadow:
    0 0 20px rgba(0, 170, 255, 0.4),
    0 0 40px rgba(100, 0, 255, 0.2),
    inset 0 0 20px rgba(0, 0, 0, 0.5);
  font-family: 'Courier New', 'Monaco', 'Menlo', monospace;
  overflow: hidden;
  position: relative;
}

.terminal-header {
  background: linear-gradient(135deg, rgba(0, 20, 50, 0.8) 0%, rgba(10, 0, 30, 0.8) 100%);
  border-bottom: 1px solid #00aaff;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 32px;
}

.terminal-controls {
  display: flex;
  gap: 6px;
}

.control-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  box-shadow: 0 0 5px currentColor;
}

.control-dot.red {
  background: #ff5f56;
  color: #ff5f56;
}

.control-dot.yellow {
  background: #ffbd2e;
  color: #ffbd2e;
}

.control-dot.green {
  background: #27ca3f;
  color: #27ca3f;
}

.terminal-body {
  height: calc(100% - 32px);
  padding: 12px;
  position: relative;
  overflow: hidden;
}

.terminal-content {
  height: 100%;
  position: relative;
}

.terminal-line {
  position: absolute;
  left: 0;
  right: 0;
  min-height: 40px;
  height: auto;
  display: flex;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.5;
  transition: transform 1.2s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.8s ease-out;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow: visible;
  bottom: 0;
  padding-right: 12px;
  padding-top: 6px;
  padding-bottom: 8px;
  margin-bottom: 4px;
}

.prompt {
  display: none;
}

.command {
  color: #66ccff;
  text-shadow:
    0 0 5px rgba(102, 204, 255, 0.6),
    0 0 10px rgba(0, 170, 255, 0.3);
  font-family: 'Courier New', monospace;
  flex: 1;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow: hidden;
  text-overflow: ellipsis;
  max-height: 54px; /* 限制最大高度 */
  width: 100%;
}

.terminal-line.typing .command {
  animation: typeGlow 1.5s ease-in-out infinite;
  color: #88ddff;
}

@keyframes typeGlow {
  0% {
    text-shadow:
      0 0 5px rgba(102, 204, 255, 0.6),
      0 0 10px rgba(0, 170, 255, 0.3);
  }
  50% {
    text-shadow:
      0 0 15px rgba(102, 204, 255, 1),
      0 0 25px rgba(0, 170, 255, 0.8),
      0 0 35px rgba(100, 0, 255, 0.5);
    color: #aaeeff;
  }
  100% {
    text-shadow:
      0 0 5px rgba(102, 204, 255, 0.6),
      0 0 10px rgba(0, 170, 255, 0.3);
  }
}

.cursor {
  color: #00aaff;
  animation: blink 1s infinite;
  margin-left: 2px;
  text-shadow:
    0 0 10px rgba(0, 170, 255, 0.9),
    0 0 20px rgba(0, 170, 255, 0.5);
  font-weight: bold;
  display: inline-block;
  font-size: 14px;
}

@keyframes blink {
  0%,
  50% {
    opacity: 1;
    transform: scaleY(1);
  }
  51%,
  100% {
    opacity: 0;
    transform: scaleY(0.8);
  }
}

.scan-line {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(0, 170, 255, 0.8),
    rgba(100, 0, 255, 0.6),
    rgba(0, 170, 255, 0.8),
    transparent
  );
  animation: scanLine 3s linear infinite;
  pointer-events: none;
  z-index: 10;
  box-shadow:
    0 0 15px rgba(0, 170, 255, 0.6),
    0 0 25px rgba(100, 0, 255, 0.3);
}

@keyframes scanLine {
  0% {
    transform: translateY(-100%);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translateY(calc(100vh));
    opacity: 0;
  }
}

/* 科技感背景效果 */
.hacker-terminal::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image:
    radial-gradient(circle at 20% 80%, rgba(0, 170, 255, 0.12) 0%, transparent 50%),
    radial-gradient(circle at 80% 20%, rgba(100, 0, 255, 0.1) 0%, transparent 50%),
    radial-gradient(circle at 40% 40%, rgba(0, 170, 255, 0.08) 0%, transparent 50%),
    radial-gradient(circle at 60% 60%, rgba(150, 50, 255, 0.06) 0%, transparent 50%);
  pointer-events: none;
  z-index: 1;
}

.terminal-body {
  z-index: 2;
  position: relative;
}

/* 打字完成后的行样式 */
.terminal-line.completed {
  opacity: 0.7;
}

.terminal-line.completed .command {
  color: #4488cc;
  text-shadow: 0 0 3px rgba(68, 136, 204, 0.4);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .terminal-line {
    font-size: 11px;
    height: 30px;
    padding-right: 8px;
  }

  .terminal-header {
    padding: 6px 10px;
    height: 28px;
  }

  .control-dot {
    width: 10px;
    height: 10px;
  }

  .prompt {
    margin-right: 6px;
  }

  .command {
    font-size: 10px;
  }
}

/* 滚动条样式 */
.terminal-body::-webkit-scrollbar {
  width: 6px;
}

.terminal-body::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.3);
}

.terminal-body::-webkit-scrollbar-thumb {
  background: rgba(0, 170, 255, 0.4);
  border-radius: 3px;
}

.terminal-body::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 170, 255, 0.6);
}
</style>
